//-----------------------------------------------------------------------
// <copyright file="MLMainForm.cs" company="MAPILab Ltd">
//     Copyright (c) MAPILab Ltd.  All rights reserved.
// </copyright>
//-----------------------------------------------------------------------
namespace MAPILab.SharePoint.Explorer
{
    using System;
    using System.Collections.Generic;
    using System.Collections.Specialized;
    using System.ComponentModel;
    using System.Configuration;
    using System.DirectoryServices;
    using System.Drawing;
    using System.IO;
    using System.Windows.Forms;
    using System.Xml;
    using MAPILab.SharePoint.Explorer.CodeForm;
    using MAPILab.SharePoint.Explorer.Information;
    using MAPILab.SharePoint.Explorer.Managment;
    using MAPILab.SharePoint.Explorer.ObjectBrowser;
    using MAPILab.SharePoint.Explorer.Properties;
    using MAPILab.SharePoint.Explorer.Utilities;
    using MAPILab.SharePoint.Explorer.Utilities.ScriptRunner;
    using Microsoft.SharePoint.Administration;
    using Microsoft.SharePoint.Upgrade;

    /// <summary>
    /// Main form of the project
    /// </summary>
    public partial class MLMainForm : Form
    {
        #region Fields

        /// <summary>
        /// Current code language
        /// </summary>
        private CodeLanguage codeLanguage;

        #endregion

        #region Constructor

        /// <summary>
        /// Default constructor
        /// </summary>
        public MLMainForm()
        {
            InitializeComponent();

            Async.Checked = Properties.Settings.Default.UseAsyncMethod;
            asyncModeToolStripMenuItem.Checked = Properties.Settings.Default.UseAsyncMethod;
            if (Async.Checked)
            {
                Async.Image = Properties.Resources.Enabled;
            }
            else
            {
                Async.Image = Properties.Resources.CancelIcon;
            }

            //Choose Icon for Button
            ChooseButtonIcon();

            this.dockPanel.ActiveDocumentChanged += new EventHandler(dockPanel1_ActiveDocumentChanged);
        }

        #endregion

        #region Overridden methods

        /// <summary>
        /// Overriding form closing method
        /// </summary>
        /// <param name="e"></param>
        protected override void OnClosing(CancelEventArgs e)
        {
            this.dockPanel.ActiveDocumentChanged -= new EventHandler(dockPanel1_ActiveDocumentChanged);
            base.OnClosing(e);
        }

        #endregion

        #region Events

        /// <summary>
        /// Change main form text when active document change
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dockPanel1_ActiveDocumentChanged(object sender, EventArgs e)
        {
            if (this.dockPanel.DocumentsCount > 0)
            {
                //TRY CATCH nessesary
                try
                {
                    this.Text = Resources.ProductName + " :: " + dockPanel.ActiveDocument.DockHandler.TabText;
                }
                catch
                {
                }
            }
            else
            {
                this.Text = Resources.ProductName;
            }
        }

        /// <summary>
        /// Close item click
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void closeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        /// <summary>
        /// Create new code window
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void codeWindowToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // Create code form
            Dictionary<string, object> allCheckObjects = CreateCodeParameters();
            MLCodeForm codeForm = new MLCodeForm();
            codeForm.CodeLanguage = codeLanguage;
            codeForm.ParametersObject = allCheckObjects;
            codeForm.MainForm = this;

            // Show code form
            ShowMDIChild(codeForm);
        }

        /// <summary>
        /// Uncheck all cheked notes
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void clearAllChecksToolStripMenuItem_Click(object sender, EventArgs e)
        {
            foreach (Form children in this.MdiChildren)
            {
                if (children is MLObjectBrowser)
                {
                    MLObjectBrowser objectBrowser = children as MLObjectBrowser;
                    objectBrowser.UncheckAll();
                }
            }
        }

        /// <summary>
        /// Show Explorer Help
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ShowHelp(object sender, EventArgs e)
        {
            MLHtmlHelper.ShowTopic(this, "explorer", 101);
        }

        /// <summary>
        /// Show about window
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            MLAbout about = new MLAbout();
            about.ShowDialog();
        }

        /// <summary>
        /// After form shown open window with root or other object
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MLMainForm_Shown(object sender, EventArgs e)
        {
            this.Refresh();

            bool updateSettings = false;

            if (Settings.Default.firstStart)
            {
                updateSettings = FirstTimeLoad();
            }

            if (updateSettings)
            {
                Application.Restart();
            }
            else
            {
                if (Properties.Settings.Default.UseAsyncMethod)
                {
                    BackgroundWorker runScriptsOnStartup = new BackgroundWorker();
                    runScriptsOnStartup.DoWork += new DoWorkEventHandler(runScriptsOnStartup_DoWork);
                    runScriptsOnStartup.RunWorkerCompleted += new RunWorkerCompletedEventHandler(runScriptsOnStartup_RunWorkerCompleted);
                    runScriptsOnStartup.RunWorkerAsync();
                }
                else
                {
                    List<MLObjectBrowser> forms = FormShown();

                    foreach (MLObjectBrowser form in forms)
                    {
                        ShowMDIChild(form);
                    }
                }
            }
        }

        /// <summary>
        /// Run scripts on startup
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void runScriptsOnStartup_DoWork(object sender, DoWorkEventArgs e)
        {
            e.Result = FormShown();
        }

        /// <summary>
        /// Show results after script run on startup
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void runScriptsOnStartup_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Result is List<MLObjectBrowser>)
            {
                List<MLObjectBrowser> forms = e.Result as List<MLObjectBrowser>;

                foreach (MLObjectBrowser form in forms)
                {
                    ShowMDIChild(form);
                }
            }
        }

        /// <summary>
        /// Align active document to bottom
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tileHorizontally(object sender, EventArgs e)
        {
            ChangeAlignment(Docking.DockAlignment.Bottom);
        }

        /// <summary>
        /// Align active document to right
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tileVertically(object sender, EventArgs e)
        {
            ChangeAlignment(Docking.DockAlignment.Right);
        }

        /// <summary>
        /// Show stored scripts
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void startupScriptsToolStripMenuItem_DropDownOpening(object sender, EventArgs e)
        {
            int currentIndex = 0;

            ToolStripItemCollection items = startupScriptsToolStripMenuItem.DropDownItems;
            ToolStripItemCollection toolBarItems = toolStripDropDownButton1.DropDownItems;

            ClearOldScripts(items);
            ClearOldScripts(toolBarItems);

            currentIndex = AppendScriptsToMenu(currentIndex, items, Settings.Default.startupScripts, true);
            currentIndex = AppendScriptsToMenu(currentIndex, items, Settings.Default.storedScripts, false);

            currentIndex = 0;

            currentIndex = AppendScriptsToMenu(currentIndex, toolBarItems, Settings.Default.startupScripts, true);
            currentIndex = AppendScriptsToMenu(currentIndex, toolBarItems, Settings.Default.storedScripts, false);
        }

        /// <summary>
        /// Open stored script manager
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void manageToolStripMenuItem_Click(object sender, EventArgs e)
        {
            MLManageScripts dlg = new MLManageScripts();
            dlg.MainForm = this;
            dlg.ShowDialog();
        }

        /// <summary>
        /// Stored script run
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void startupScriptsToolStripMenuItem_DropDownItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            try
            {
                if (e.ClickedItem.Tag is string)
                {
                    string root = e.ClickedItem.Tag as string;
                    if (!root.Contains("\\"))
                    {
                        //For scripts thet generated automaticly
                        root = MLUtils.GetRoot() + root;
                    }

                    if (Settings.Default.UseAsyncMethod)
                    {
                        BackgroundWorker startupScriptsExecutor = new BackgroundWorker();
                        startupScriptsExecutor.RunWorkerCompleted += new RunWorkerCompletedEventHandler(startupScriptsExecutor_RunWorkerCompleted);
                        startupScriptsExecutor.DoWork += new DoWorkEventHandler(startupScriptsExecutor_DoWork);
                        startupScriptsExecutor.RunWorkerAsync(root);
                    }
                    else
                    {
                        ShowMDIChild(ExecuteStoredScript(root, false));
                    }
                }
            }
            catch (Exception ex)
            {
                CheckExceptionToDisplay(ex, (e.ClickedItem.Tag as string));
            }
        }

        /// <summary>
        /// Run stored script async
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void startupScriptsExecutor_DoWork(object sender, DoWorkEventArgs e)
        {
            e.Result = ExecuteStoredScript(e.Argument as string, false);
        }

        /// <summary>
        /// Show window after complete run script async
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void startupScriptsExecutor_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Result is MLObjectBrowser)
            {
                ShowMDIChild(e.Result as MLObjectBrowser);
            }
        }

        /// <summary>
        /// Lock layouts
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void lockLayouts(object sender, EventArgs e)
        {
            dockPanel.AllowEndUserDocking = !dockPanel.AllowEndUserDocking;
            lockLayoutsToolStripMenuItem.Checked = !dockPanel.AllowEndUserDocking;
            lockLayoutsToolStripMenuItem1.Checked = !dockPanel.AllowEndUserDocking;
        }

        /// <summary>
        /// Show properties
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void optionsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            MLOptionsForm propertiesForm = new MLOptionsForm();
            DialogResult result = propertiesForm.ShowDialog();
            if (result == DialogResult.OK)
            {
                ChooseButtonIcon();
            }
        }

        /// <summary>
        /// Close active document
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void closeToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            dockPanel.ActiveDocument.DockHandler.Close();
        }

        /// <summary>
        /// Close all documents clicked
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void closeAllButThisItem_Click(object sender, EventArgs e)
        {
            if (dockPanel.ActiveDocument != null)
            {
                Docking.IDockContent content = dockPanel.ActiveDocument.DockHandler.Content;

                Docking.IDockContent[] dockContent = dockPanel.DocumentsToArray();

                for (int i = dockContent.Length - 1; i >= 0; i--)
                {
                    if (!dockContent[i].Equals(content))
                        dockContent[i].DockHandler.Close();
                }
            }
        }

        /// <summary>
        /// Close all documents but this clicked
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void closeAllItem_Click(object sender, EventArgs e)
        {
            Docking.IDockContent[] dockContent = dockPanel.DocumentsToArray();

            for (int i = dockContent.Length - 1; i >= 0; i--)
            {
                dockContent[i].DockHandler.Close();
            }
        }

        /// <summary>
        /// Async mode
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Async_Click(object sender, EventArgs e)
        {
            if (sender is ToolStripDropDownItem)
            {
                Properties.Settings.Default.UseAsyncMethod = asyncModeToolStripMenuItem.Checked;
                Async.Checked = asyncModeToolStripMenuItem.Checked;
                if (Async.Checked)
                {
                    Async.Image = Properties.Resources.Enabled;
                }
                else
                {
                    Async.Image = Properties.Resources.CancelIcon;
                }
            }
            else
            {
                Properties.Settings.Default.UseAsyncMethod = Async.Checked;
                asyncModeToolStripMenuItem.Checked = Async.Checked;
                if (Async.Checked)
                {
                    Async.Image = Properties.Resources.Enabled;
                }
                else
                {
                    Async.Image = Properties.Resources.CancelIcon;
                }
            }
            Properties.Settings.Default.Save();

            if (Properties.Settings.Default.UseAsyncMethod)
            {
                foreach (Form form in this.MdiChildren)
                {
                    if ((form is MLObjectBrowser) && (form as MLObjectBrowser).IsRunning)
                    {
                        Abort.Enabled = true;
                        abortToolStripMenuItem.Enabled = true;
                        return;
                    }
                }
            }

            Abort.Enabled = false;
            abortToolStripMenuItem.Enabled = false;
        }

        /// <summary>
        /// Abort all threads
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Abort_Click(object sender, EventArgs e)
        {
            foreach (Form children in this.MdiChildren)
            {
                if (children is MLObjectBrowser)
                {
                    MLObjectBrowser objectBrowser = children as MLObjectBrowser;
                    if (objectBrowser.AsyncWorker != null)
                        objectBrowser.AsyncWorker.Dispose();
                }
            }

            Abort.Enabled = false;
            abortToolStripMenuItem.Enabled = false;
        }

        #endregion

        #region Methods

        /// <summary>
        /// Load all default scripts
        /// </summary>
        private List<MLObjectBrowser> FormShown()
        {
            bool sharePointLoaded = false;

            //Add rules to display items of enumerable objects
            MLUtils.AddRules();

            bool loadDefaultScript = false;
            bool loadSturtupScripts = false;
            int numberOfScripts = 0;
            if (!Settings.Default.skipDefaultLoading)
            {
                numberOfScripts++;
                loadDefaultScript = true;
            }
            if (Settings.Default.startupScripts != null && Settings.Default.startupScripts.Count > 0)
            {
                numberOfScripts = numberOfScripts + Settings.Default.startupScripts.Count;
                loadSturtupScripts = true;
            }

            List<MLObjectBrowser> forms = new List<MLObjectBrowser>(numberOfScripts);

            try
            {
                //Default form loading
                if (loadDefaultScript)
                {
                    MLObjectBrowser form = new MLObjectBrowser();

                    try
                    {
                        //Loading with SharePoint
                        SPFarm farm = SPFarm.Local;
                        if (farm != null)
                        {
                            form.Text = "Start Page";
                            form.BrowsedObjects = new object[]
                            {
                                farm,
                                SPManager.Instance
                            };

                            sharePointLoaded = true;
                        }
                    }
                    catch
                    {
                        sharePointLoaded = false;
                    }

                    if (!sharePointLoaded)
                    {
                        //Loading with non SharePoint
                        form.BrowsedObjects = new object[] { new DirectoryEntry() };
                        form.Text = form.BrowsedObjects[0].ToString();

                        sharePointLoaded = true;
                    }

                    forms.Add(form);
                }

                //Execute default startups scripts
                if (loadSturtupScripts)
                {
                    forms.AddRange(ExecuteDefaultStartupScripts());
                }
            }
            catch (Exception ex)
            {
                DisplayException(ex);
            }

            return forms;
        }

        /// <summary>
        /// Show MDI Child Form
        /// </summary>
        /// <param name="Form">Child Form</param>
        private void ShowMDIChild(Docking.DockContent Form)
        {
            if (dockPanel.DocumentStyle == Docking.DocumentStyle.SystemMdi)
            {
                Form.MdiParent = this;
                Form.Show();
            }
            else
                Form.Show(dockPanel);
        }

        /// <summary>
        /// Execute default startup scripts and remove failed script from startup
        /// </summary>
        private List<MLObjectBrowser> ExecuteDefaultStartupScripts()
        {
            List<MLObjectBrowser> forms = new List<MLObjectBrowser>(Settings.Default.startupScripts.Count);

            StringCollection errorScriptFiles = new StringCollection();
            foreach (string scriptFile in Settings.Default.startupScripts)
            {
                try
                {
                    MLObjectBrowser form = ExecuteStoredScript(scriptFile, true);
                    if (form != null)
                    {
                        forms.Add(form);
                    }
                }
                catch (Exception ex)
                {
                    if (ex.Message.Contains("Could not find file"))
                    {
                        errorScriptFiles.Add(scriptFile);
                    }
                    else
                    {
                        throw new NotImplementedException(ex.Message, ex.InnerException);
                    }
                }
            }

            foreach (string scriptFile in errorScriptFiles)
            {
                MessageBox.Show("Could not find file " + scriptFile, Resources.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
                if (Settings.Default.startupScripts.Contains(scriptFile))
                {
                    Settings.Default.startupScripts.Remove(scriptFile);
                    Settings.Default.Save();
                }
            }

            return forms;
        }

        /// <summary>
        /// Choose button icon
        /// </summary>
        private void ChooseButtonIcon()
        {
            if (Settings.Default.CodeLanguage == "VBNet")
            {
                codeLanguage = CodeLanguage.VBNet;
                toolStripButtonNewCodeWindow.Image = Resources.VBNetCodeFileIcon.ToBitmap();
                codeWindowToolStripMenuItem.Image = Resources.VBNetCodeFileIcon.ToBitmap();
                toolStripDropDownButton1.Image = Resources.VBNetIcon.ToBitmap();
                startupScriptsToolStripMenuItem.Image = Resources.VBNetIcon.ToBitmap();
            }
            else
            {
                codeLanguage = CodeLanguage.CSharp;
                toolStripButtonNewCodeWindow.Image = Resources.CSharpCodeFileIcon.ToBitmap();
                codeWindowToolStripMenuItem.Image = Resources.CSharpCodeFileIcon.ToBitmap();
                toolStripDropDownButton1.Image = Resources.CSharpIcon.ToBitmap();
                startupScriptsToolStripMenuItem.Image = Resources.CSharpIcon.ToBitmap();
            }
        }

        /// <summary>
        /// Create source code parameters
        /// </summary>
        /// <returns>Code parameters</returns>
        private Dictionary<string, object> CreateCodeParameters()
        {
            Dictionary<string, object> allCheckObjects = new Dictionary<string, object>();

            foreach (Form children in this.MdiChildren)
            {
                if (children is MLObjectBrowser)
                {
                    MLObjectBrowser objectForm = children as MLObjectBrowser;
                    Dictionary<string, object> checkObjects = objectForm.GetCheckedObjects();
                    AppendToAllObjects(allCheckObjects, checkObjects);
                }
            }

            return allCheckObjects;
        }

        /// <summary>
        /// Append All Object from first to second Dictionary
        /// </summary>
        /// <param name="allCheckObjects">first dictionary</param>
        /// <param name="checkObjects">second dictionary</param>
        void AppendToAllObjects(Dictionary<string, object> allCheckObjects, Dictionary<string, object> checkObjects)
        {
            foreach (KeyValuePair<string, object> kpv in checkObjects)
            {
                string varName = CreateVarName(allCheckObjects.Count + 1, kpv.Key);
                allCheckObjects.Add(varName, kpv.Value);
            }
        }

        /// <summary>
        /// Create variable name
        /// </summary>
        /// <param name="index">variable index</param>
        /// <param name="objectName">object name</param>
        /// <returns>variable name</returns>
        string CreateVarName(int index, string objectName)
        {
            string safeName = "";
            bool firstSymbol = true;
            int symbCount = 20;

            foreach (char ch in objectName)
            {
                if (char.IsLetterOrDigit(ch))
                {
                    char sch = ch;
                    if (firstSymbol)
                    {
                        sch = char.ToLower(sch);
                        firstSymbol = false;
                    }

                    safeName += sch;

                    if (--symbCount <= 0)
                        break;
                }
            }

            safeName += index.ToString();

            return safeName;
        }

        /// <summary>
        /// Execute selected script
        /// </summary>
        /// <param name="scriptFile">script file full path</param>
        /// <param name="zeroReport">is default startup script</param>
        private MLObjectBrowser ExecuteStoredScript(string scriptFile, bool zeroReport)
        {
            MLObjectBrowser form = null;

            try
            {
                // Load stored script
                CodeLanguage codeLanguage = MLUtils.GetCodeLanguage(scriptFile);
                if (!scriptFile.Contains("\\"))
                {
                    //For scripts that generated automaticly
                    scriptFile = MLUtils.GetRoot() + scriptFile;
                }
                string code = MLUtils.LoadCode(scriptFile);

                // Execute script
                MLExecutionResults executionResults = MLScriptRunner.Execute(code, null, null, codeLanguage);
                MLBrowser result = executionResults.ReturnedObjects;
                StringCollection errors = executionResults.ErrorsCollection;

                if (errors.Count > 0)
                {
                    // Processing execution errors
                    int i = 0;
                    string text = null;
                    text = "---------Errors-------- \n";
                    foreach (string error in errors)
                    {
                        i++;
                        text += String.Format("{0} -> {1}", i.ToString(), error);
                    }

                    MessageBox.Show(text, Resources.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    //Processing execution results
                    if (result == null || result.ReturnValue == null)
                    {
                        if (!zeroReport)
                            MessageBox.Show("Method Main return null", Resources.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                    else
                    {
                        form = new MLObjectBrowser();

                        if (result.DisplayMode == DisplayMode.Raw || !(result.ReturnValue is object[]))
                        {
                            form.BrowsedObjects = new object[] { result.ReturnValue };
                        }
                        else
                        {
                            form.BrowsedObjects = result.ReturnValue as object[];
                        }

                        if (result.Text == null)
                        {
                            form.Text = string.Format("Startup:{0}", scriptFile);
                        }
                        else
                        {
                            form.Text = result.Text;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                throw new NotImplementedException(ex.Message, ex.InnerException);
            }

            return form;
        }

        /// <summary>
        /// Clear Old Scripts
        /// </summary>
        /// <param name="items">scripts collection</param>
        private static void ClearOldScripts(ToolStripItemCollection items)
        {
            for (int i = items.Count - 1; i >= 0; i--)
            {
                if (items[i].Tag is string)
                    items.RemoveAt(i);
            }
        }

        /// <summary>
        /// Add scripts to menu
        /// </summary>
        /// <param name="currentIndex">current index in list</param>
        /// <param name="items">current items</param>
        /// <param name="scriptPaths">all scripts full paths</param>
        /// <param name="IsStartup">is sturtup script or not</param>
        /// <returns>current index in list</returns>
        private int AppendScriptsToMenu(int currentIndex, ToolStripItemCollection items, StringCollection scriptPaths, bool IsStartup)
        {
            if (scriptPaths == null)
            {
                return currentIndex;
            }

            foreach (string scriptPath in scriptPaths)
            {
                Image image;
                if (IsStartup)
                {
                    if (scriptPath.EndsWith(Resources.VBNetExtention))
                    {
                        image = Resources.VBNetStartupIcon.ToBitmap();
                    }
                    else
                    {
                        image = Resources.CSharpStartupIcon.ToBitmap();
                    }
                }
                else
                {
                    if (scriptPath.EndsWith(Resources.VBNetExtention))
                    {
                        image = Resources.VBNetIcon.ToBitmap();
                    }
                    else
                    {
                        image = Resources.CSharpIcon.ToBitmap();
                    }
                }

                ToolStripMenuItem item = new ToolStripMenuItem(scriptPath, image);
                item.Tag = scriptPath;
                items.Insert(currentIndex++, item);
            }
            return currentIndex;
        }

        /// <summary>
        /// Change active document aligment
        /// </summary>
        /// <param name="newAlignment">dock alignment</param>
        private void ChangeAlignment(Docking.DockAlignment newAlignment)
        {
            if (dockPanel.ActiveDocumentPane.Contents.Count != 1)
            {
                dockPanel.SuspendLayout(true);

                dockPanel.ActiveDocument.DockHandler.Show(dockPanel.ActiveDocumentPane, newAlignment, 0.5);

                dockPanel.ResumeLayout(true, true);
            }
        }

        /// <summary>
        /// Check exeption before display
        /// </summary>
        /// <param name="ex">exeption</param>
        /// <param name="scriptToOpen">script that is not opened</param>
        public void CheckExceptionToDisplay(Exception ex, string scriptToOpen)
        {
            if (ex.Message.Contains("Could not find file"))
            {
                MessageBox.Show(ex.Message, Resources.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
                if (Settings.Default.storedScripts.Contains(scriptToOpen))
                {
                    Settings.Default.storedScripts.Remove(scriptToOpen);
                    Settings.Default.Save();
                }
            }
            else
            {
                DisplayException(ex);
            }
        }

        /// <summary>
        /// Display Exception
        /// </summary>
        /// <param name="ex">Exception</param>
        public void DisplayException(Exception ex)
        {
            MLObjectBrowser newWindow = new MLObjectBrowser();

            Exception tex = ex;
            List<object> exceptions = new List<object>();
            while (tex != null)
            {
                exceptions.Add(tex);
                tex = tex.InnerException;
            }

            newWindow.BrowsedObjects = exceptions.ToArray();

            newWindow.Text = "Exception: " + ex.Message;

            ShowMDIChild(newWindow);
        }

        /// <summary>
        /// Add old setting on first time start
        /// </summary>
        /// <returns></returns>
        private static bool FirstTimeLoad()
        {
            bool result = false;

            Configuration roamingConfig = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal);
            DirectoryInfo directory = Directory.GetParent(roamingConfig.FilePath).Parent;

            if (directory.Exists)
            {
                string folderName = "0.0.0.0";
                DirectoryInfo[] folders = directory.GetDirectories("*.*.*.*");
                foreach (DirectoryInfo folder in folders)
                    if (folderName.CompareTo(folder.Name) == -1)
                        folderName = folder.Name;

                if (folderName != "0.0.0.0")
                {
                    string oldConfigPath = String.Format(@"{0}\\{1}\\user.config", directory.FullName, folderName);
                    if (File.Exists(oldConfigPath))
                    {
                        if (MessageBox.Show("It is the first start of the program. Would you like to get settings from the previous version?",
                                            "First Start",
                                            MessageBoxButtons.YesNo,
                                            MessageBoxIcon.Question,
                                            MessageBoxDefaultButton.Button1) == DialogResult.Yes)
                        {
                            result = GetOldSettings(directory, folderName);
                        }
                    }
                    else
                    {
                        result = SearchInFirstVersions(directory);
                    }
                }
                else
                {
                    result = SearchInFirstVersions(directory);
                }
            }
            else if (directory.Parent.Exists)
            {
                result = SearchInFirstVersions(directory);
            }

            string SharePoint_dllPath = MLUtils.GetSharePointDLLPath();
            if (!Settings.Default.references.Contains(SharePoint_dllPath))
                Settings.Default.references.Add(SharePoint_dllPath);

            Settings.Default.firstStart = false;
            Settings.Default.Save();

            return result;
        }


        private static bool SearchInFirstVersions(DirectoryInfo directory)
        {
            bool result = false;
            DirectoryInfo[] otherFolders = directory.Parent.GetDirectories(@"MLSharePointExplorer.exe_Url_jxvohwp5e3gyet1bknzfyysgmbggpfxq");
            if (otherFolders.Length == 1)
            {
                string folderName = "0.0.0.0";
                DirectoryInfo[] folders = otherFolders[0].GetDirectories("*.*.*.*");
                foreach (DirectoryInfo folder in folders)
                    if (folderName.CompareTo(folder.Name) == -1)
                        folderName = folder.Name;

                if (folderName != "0.0.0.0")
                {
                    if (MessageBox.Show("It is the first start of the program. Would you like to get settings from the previous version?",
                                        "First Start",
                                        MessageBoxButtons.YesNo,
                                        MessageBoxIcon.Question,
                                        MessageBoxDefaultButton.Button1) == DialogResult.Yes)
                    {
                        result = GetOldSettings(otherFolders[0], folderName);
                    }
                }
            }

            return result;
        }

        private static bool GetOldSettings(string oldConfigPath)
        {
            bool result = false;

            try
            {
                XmlDocument document = new XmlDocument();
                document.Load(oldConfigPath);
                XmlNode node = document.DocumentElement.LastChild.FirstChild; // MAPILab.SharePoint.Explorer.Properties.Settings

                foreach (XmlNode setting in node.ChildNodes)
                {
                    foreach (XmlAttribute attribute in setting.Attributes)
                    {
                        if (attribute.Name == "name")
                        {
                            string value = attribute.Value;

                            if (value == "references")
                            {
                                StringCollection sc = XMLProcessArrayOfString(setting);
                                if (sc.Count > 0)
                                    Settings.Default.references = sc;
                            }
                            else if (value == "namespaces")
                            {
                                StringCollection sc = XMLProcessArrayOfString(setting);
                                if (sc.Count > 0)
                                    Settings.Default.namespaces = sc;
                            }
                            else if (value == "dontShowStoredScrTip")
                            {
                                string s = XMLProcessString(setting);
                                if (!String.IsNullOrEmpty(s))
                                    Settings.Default.dontShowStoredScrTip = Convert.ToBoolean(s);
                            }
                            else if (value == "skipDefaultLoading")
                            {
                                string s = XMLProcessString(setting);
                                if (!String.IsNullOrEmpty(s))
                                    Settings.Default.skipDefaultLoading = Convert.ToBoolean(s);
                            }
                            else if (value == "UseAsyncMethod")
                            {
                                string s = XMLProcessString(setting);
                                if (!String.IsNullOrEmpty(s))
                                    Settings.Default.UseAsyncMethod = Convert.ToBoolean(s);
                            }
                            else if (value == "storedScripts")
                            {
                                StringCollection sc = XMLProcessArrayOfString(setting);
                                if (sc.Count > 0)
                                    Settings.Default.storedScripts = sc;
                            }
                            else if (value == "startupScripts")
                            {
                                StringCollection sc = XMLProcessArrayOfString(setting);
                                if (sc.Count > 0)
                                    Settings.Default.startupScripts = sc;
                            }
                            else if (value == "WordWrap")
                            {
                                string s = XMLProcessString(setting);
                                if (!String.IsNullOrEmpty(s))
                                    Settings.Default.WordWrap = Convert.ToBoolean(s);
                            }
                            else if (value == "NumberOfThreads")
                            {
                                string s = XMLProcessString(setting);
                                if (!String.IsNullOrEmpty(s))
                                    Settings.Default.NumberOfThreads = Convert.ToInt32(s);
                            }
                            else if (value == "CodeLanguage")
                            {
                                string s = XMLProcessString(setting);
                                if (!String.IsNullOrEmpty(s))
                                    Settings.Default.CodeLanguage = s;
                            }
                            else if (value == "rulesToDisplay")
                            {
                                StringCollection sc = XMLProcessArrayOfString(setting);
                                if (sc.Count > 0)
                                    Settings.Default.rulesToDisplay = sc;
                            }

                            break;
                        }
                    }
                }

                result = true;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, Properties.Resources.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            return result;
        }

        private static bool GetOldSettings(DirectoryInfo directory, string folderName)
        {
            string oldConfigPath = String.Format(@"{0}\\{1}\\user.config", directory.FullName, folderName);

            return GetOldSettings(oldConfigPath);
        }

        /// <summary>
        /// Search for string collection in settings
        /// </summary>
        /// <param name="setting">setting node</param>
        /// <returns>String Collection from setting node</returns>
        private static StringCollection XMLProcessArrayOfString(XmlNode setting)
        {
            StringCollection values = new StringCollection();

            XmlNode property = setting.FirstChild.FirstChild; // ArrayOfString
            if (property.HasChildNodes)
                foreach (XmlNode node in property.ChildNodes)
                    values.Add(node.InnerText);

            return values;
        }

        /// <summary>
        /// Search for string in settings
        /// </summary>
        /// <param name="setting">setting node</param>
        /// <returns>string from setting node</returns>
        private static string XMLProcessString(XmlNode setting)
        {
            return setting.FirstChild.InnerText;
        }

        #endregion
    }
}